#include "Shader.h"
#include <iostream>
CGcontext Shader::cgContext;
CGprofile Shader::cgVertexProfile;
CGprofile Shader::cgFragmentProfile;

unsigned float Shader::timer1;

Shader::Shader()
{
}

Shader::Shader(std::string path)
{


	cgVertexProgram = cgCreateProgramFromFile(cgContext, CG_SOURCE, path.c_str(), cgVertexProfile, "main", 0);
	cgGLLoadProgram(cgVertexProgram);

	//mvp = cgGetNamedParameter(cgVertexProgram, "mvp");
}

Shader::Shader(std::string path, std::string mainFunction, bool isFrag)
{
	if(!isFrag)
	{
		cgFragmentProgram = NULL;
		cgVertexProgram = cgCreateProgramFromFile(cgContext, CG_SOURCE, path.c_str(), cgVertexProfile, mainFunction.c_str(), 0);
		cgGLLoadProgram(cgVertexProgram);

		if(cgVertexProgram == NULL)
			std::cout << "Failed to load/compile shader " << path << "\n";

		mvp = cgGetNamedParameter(cgVertexProgram, "mvp");
		sTimer1 = cgGetNamedParameter(cgVertexProgram, "timer1");

	}else{
		cgVertexProgram = NULL;
		mvp = NULL;
		cgFragmentProgram = cgCreateProgramFromFile(cgContext, CG_SOURCE, path.c_str(), cgFragmentProfile, mainFunction.c_str(), 0);
		cgGLLoadProgram(cgFragmentProgram);

		if(cgFragmentProgram == NULL)
			std::cout << "Failed to load/compile shader " << path << "\n";


		sTimer1 = cgGetNamedParameter(cgFragmentProgram, "timer1");
	} 

}

Shader::Shader(std::string path, std::string mainFunction, std::string pathFrag, std::string mainFrag)
{
	/*
	cgVertexProgram = cgCreateProgramFromFile(cgContext, CG_SOURCE, path.c_str(), cgVertexProfile, mainFunction.c_str(), 0);
	cgGLLoadProgram(cgVertexProgram);

	if(cgVertexProgram == NULL)
		std::cout << "Failed to load/compile shader " << path << "\n";

	mvp = cgGetNamedParameter(cgVertexProgram, "mvp");

	cgFragmentProgram = cgCreateProgramFromFile(cgContext, CG_SOURCE, pathFrag.c_str(), cgFragmentProfile, mainFrag.c_str(), 0);
	cgGLLoadProgram(cgFragmentProgram);

	if(cgFragmentProgram == NULL)
		std::cout << "Failed to load/compile shader " << pathFrag << "\n";
	*/
}


Shader::~Shader(void)
{
	cgDestroyProgram(cgVertexProgram);
	cgDestroyProgram(cgFragmentProgram);
}











void Shader::updateTimers()
{
	timer1++;
}

void Shader::destroyShaderContext()
{
	cgDestroyContext(cgContext);
}

void Shader::initializeShaderContext()
{
	timer1 = 1;



	cgContext = cgCreateContext();
	cgGLSetDebugMode(CG_FALSE);

	if (cgContext == NULL)
	{
		std::cout << "Failed to create cg context.\n";

	}

	cgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
	if (cgVertexProfile == CG_PROFILE_UNKNOWN)
	{
		std::cout << "Invalid profile type.\n";
	}
	cgGLSetOptimalOptions(cgVertexProfile);

	cgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
	if (cgFragmentProfile == CG_PROFILE_UNKNOWN)
	{
		std::cout << "Invalid profile type.\n";
	}
	cgGLSetOptimalOptions(cgFragmentProfile);
}


void Shader::enable()
{

	if(sTimer1 != NULL)
		cgSetParameter1f(sTimer1, timer1);
	if(mvp != NULL)
		cgGLSetStateMatrixParameter(mvp, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);

	if(cgVertexProgram != NULL)
	{
		cgGLEnableProfile(cgVertexProfile);
		cgGLBindProgram(cgVertexProgram);
	}
	
	if(cgFragmentProgram != NULL)
	{
		cgGLEnableProfile(cgFragmentProfile);
		cgGLBindProgram(cgFragmentProgram);
	}



}

void Shader::disable()
{
	if(cgFragmentProgram != NULL)
		cgGLDisableProfile(cgFragmentProfile);
	if(cgVertexProgram != NULL)
		cgGLDisableProfile(cgVertexProfile);
}

